package com.mf.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mf.entity.bo.BasicResourceFileBo;
import com.mf.entity.request.upload.FileFindPageListReq;
import com.mf.entity.request.upload.FileInitSliceDataReq;
import com.mf.entity.request.upload.FileUploadFileReq;
import com.mf.entity.vo.BasicFileVo;
import com.mf.enums.EnumBasicResultCode;
import com.mf.enums.EnumDataDictionaryType;
import com.mf.enums.EnumFilePublicType;
import com.mf.service.upload.IBasicResourceFileService;
import com.mf.service.upload.IFileUploadProcess;
import io.github.heollhai.common.config.exceptions.GraceException;
import io.github.heollhai.common.result.Result;
import io.github.heollhai.common.utils.enums.EnumUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @Author: lmf
 * @Create: 2024/11/20 21:09
 * Description:  文件上传
 */
@Validated
@RestController
@Tag(name = "文件管理")
@RequestMapping("basic/file/v1")
public class FileUploadController {
    @Resource
    private IFileUploadProcess fileUploadProcess;
    @Resource
    private IBasicResourceFileService resourceFileService;


    /**
     * 文件上传
     */
    @Operation(summary = "文件上传")
    @PostMapping("/upload/file")
    public Result<String> uploadFile(@Valid @ModelAttribute FileUploadFileReq fileUploadFileReq) {
        fileUploadProcess.uploadFile(fileUploadFileReq);
        return Result.success();
    }

    /**
     * 检查是否上传过文件
     *
     * @return true：已上传过,false：没有上传过
     */
    @Operation(summary = "检查是否上传过文件")
    @PostMapping("isExist/file")
    public Result<Integer> checkIsUploadFile(@Valid @RequestBody FileInitSliceDataReq fileInitSliceDataReq) {
        return Result.success(resourceFileService.checkIsExistFile(fileInitSliceDataReq));
    }

    @Operation(summary = "查询文件列表")
    @PostMapping("findPageList")
    public Result<Page<BasicFileVo>> findPageList(@Valid @RequestBody FileFindPageListReq fileFindPageListReq) {
        return Result.success(resourceFileService.findPageList(fileFindPageListReq));
    }

    @Operation(summary = "根据文件id删除")
    @GetMapping("delete/{id}")
    public Result<Integer> deleteById(@PathVariable("id") Integer id) {
        return Result.success(fileUploadProcess.deleteById(id));
    }

    @Operation(summary = "获取预览图片权限")
    @GetMapping("getFileToken/{id}")
    public Result<String> getImageToken(@PathVariable("id") Integer id) {
        return Result.success(resourceFileService.getFileToken(id));
    }

    @Operation(summary = "批量获取图片权限")
    @GetMapping("bachGetFileToken")
    public Result<List<String>> bachGetFileToken(@RequestParam("ids") String ids) {
        return Result.success(resourceFileService.bachGetFileToken(ids));
    }

    @Operation(summary = "文件预览")
    @GetMapping("preview/{id}/{fileToken}")
    public ResponseEntity<InputStreamResource> previewById(@PathVariable("id") Integer id,
                                                           @PathVariable("fileToken") String fileToken) {
        return resourceFileService.previewById(id, fileToken);
    }

    @Operation(summary = "预览公共图片")
    @GetMapping("previewPublic/{area}/{type}/{bindId}/{md5}/{originName}/{bucket}")
    public ResponseEntity<InputStreamResource> previewPublicId(
            @PathVariable("area") String area,
            @PathVariable("type") String type,
            @PathVariable("bindId") String bindId,
            @PathVariable("md5") String md5,
            @PathVariable("originName") String originName,
            @PathVariable("bucket") String bucket
    ) {
        // 非公共文件不能直接预览
        if (EnumUtils.existsInEnum(EnumFilePublicType.class, type)) {
            GraceException.display(EnumBasicResultCode.FILE_NOT_EXIST);
        }
        BasicResourceFileBo basicResourceFileBo = BasicResourceFileBo.builder()
                .fileArea(area)
                .fileBindId(bindId)
                .fileType(type)
                .minioMd5(md5)
                .originalFileName(originName)
                .minioBucket(bucket)
                .build();
        return resourceFileService.getMinioFile(basicResourceFileBo);
    }

    @Operation(summary = "根据id获取文件信息")
    @GetMapping("findById/{id}")
    public Result<BasicResourceFileBo> findById(@PathVariable("id") Integer id) {
        return Result.success(resourceFileService.selectById(id));
    }

    /**
     * 文件初始化
     * 1.创建桶
     * 2.将分片索引放入到redis中
     * 3.将分片以及对应基本信息先存储到资源附件中(resourceFile)
     */
    @Operation(summary = "文件初始化")
    @PostMapping("init/fileData")
    public Result<String> initFileData(@RequestBody @Valid FileInitSliceDataReq fileInitSliceDataReq) {
        fileUploadProcess.initFileData(fileInitSliceDataReq);
        return Result.success();
    }
}
